package cn.tedu.tmall.front.mall.service.impl;

import cn.tedu.tmall.common.enumerator.ServiceCode;
import cn.tedu.tmall.common.ex.ServiceException;
import cn.tedu.tmall.common.pojo.authentication.CurrentPrincipal;
import cn.tedu.tmall.front.mall.converter.GoodsToCartConverter;
import cn.tedu.tmall.front.mall.dao.cache.ICartCacheRepository;
import cn.tedu.tmall.front.mall.dao.persist.repository.IGoodsRepository;
import cn.tedu.tmall.front.mall.pojo.po.CartPO;
import cn.tedu.tmall.front.mall.pojo.vo.CartListItemVO;
import cn.tedu.tmall.front.mall.pojo.vo.GoodsStandardVO;
import cn.tedu.tmall.front.mall.service.ICartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 处理购物车的业务实现类
 *
 * @author java@tedu.cn
 * @version 3.0
 */
@Slf4j
@Service
public class CartServiceImpl implements ICartService {

    @Autowired
    private ICartCacheRepository cartCacheRepository;
    @Autowired
    private IGoodsRepository goodsRepository;

    public CartServiceImpl() {
        log.debug("创建业务类对象：CartServiceImpl");
    }

    @Override
    public void add(CurrentPrincipal currentPrincipal, Long goodsId, Integer goodsNum) {
        log.debug("开始处理【添加商品到购物车】的业务，当事人：{}，商品：{}，数量：{}", currentPrincipal, goodsId, goodsNum);
        GoodsStandardVO goods = goodsRepository.getStandardById(goodsId);
        if (goods == null) {
            String message = "添加购物车失败，商品数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        if (goods.getIsPutOn() != 1) {
            String message = "添加购物车失败，商品已下架！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        CartPO.CartInfo cartInfo = new CartPO.CartInfo(1, goodsNum, goods.getSalePrice());

        CartPO cartCache = cartCacheRepository.getByUserAndGoods(currentPrincipal.getId(), goodsId);
        if (cartCache != null) {
            cartInfo.setGoodsNum(cartCache.getCartInfo().getGoodsNum() + goodsNum);
        }

        CartPO cartPO = new CartPO(goodsId, cartInfo);
        cartCacheRepository.addNew(currentPrincipal.getId(), cartPO);
    }

    @Override
    public void delete(CurrentPrincipal currentPrincipal, Long goodsId) {
        log.debug("开始处理【删除购物车中的商品】的业务，当事人：{}，商品：{}", currentPrincipal, goodsId);
        cartCacheRepository.deleteByUserAndGoods(currentPrincipal.getId(), goodsId);
    }

    @Override
    public void check(CurrentPrincipal currentPrincipal, Long goodsId) {
        log.debug("开始处理【勾选购物车中的商品】的业务，当事人：{}，商品：{}", currentPrincipal, goodsId);
        updateCheckState(currentPrincipal.getId(), goodsId, 1);
    }

    @Override
    public void uncheck(CurrentPrincipal currentPrincipal, Long goodsId) {
        log.debug("开始处理【取消勾选购物车中的商品】的业务，当事人：{}，商品：{}", currentPrincipal, goodsId);
        updateCheckState(currentPrincipal.getId(), goodsId, 0);
    }

    @Override
    public Integer increaseNum(CurrentPrincipal currentPrincipal, Long goodsId) {
        log.debug("开始处理【将购物车中商品的数量增加1】的业务，当事人：{}，商品：{}", currentPrincipal, goodsId);
        return increaseNum(currentPrincipal.getId(), goodsId, 1);
    }

    @Override
    public Integer increaseNum(CurrentPrincipal currentPrincipal, Long goodsId, Integer num) {
        log.debug("开始处理【增加购物车中商品的数量】的业务，当事人：{}，商品：{}，数量：{}", currentPrincipal, goodsId, num);
        return increaseNum(currentPrincipal.getId(), goodsId, num);
    }

    @Override
    public Integer reduceNum(CurrentPrincipal currentPrincipal, Long goodsId) {
        log.debug("开始处理【将购物车中商品的数量减少1】的业务，当事人：{}，商品：{}", currentPrincipal, goodsId);
        return reduceNum(currentPrincipal.getId(), goodsId, 1);
    }

    @Override
    public Integer reduceNum(CurrentPrincipal currentPrincipal, Long goodsId, Integer num) {
        log.debug("开始处理【减少购物车中商品的数量】的业务，当事人：{}，商品：{}，数量：{}", currentPrincipal, goodsId, num);
        return reduceNum(currentPrincipal.getId(), goodsId, num);
    }

    @Override
    public List<CartListItemVO> list(CurrentPrincipal currentPrincipal) {
        log.debug("开始处理【查询购物车列表】的业务，当事人：{}", currentPrincipal);
        List<CartListItemVO> cartList = new ArrayList<>();
        List<CartPO> cartPOList = cartCacheRepository.listByUser(currentPrincipal.getId());
        for (CartPO cartPO : cartPOList) {
            GoodsStandardVO goods = goodsRepository.getStandardById(cartPO.getGoodsId());
            if (goods != null) {
                CartListItemVO cartListItemVO = GoodsToCartConverter.convertToCart(cartPO, goods);
                cartList.add(cartListItemVO);
            }
        }
        return cartList;
    }

    private void updateCheckState(Long userId, Long goodsId, Integer newCheckState) {
        checkGoodsState(goodsId);
        cartCacheRepository.updateCheckStateByUserAndGoods(userId, goodsId, newCheckState);
    }

    /**
     * 增加购物车中的商品的数量
     *
     * @param userId  用户ID
     * @param goodsId 商品ID
     * @param num     增加的商品的数量
     * @return 新的数量
     */
    private Integer increaseNum(Long userId, Long goodsId, Integer num) {
        checkGoodsState(goodsId);

        CartPO cartCache = cartCacheRepository.getByUserAndGoods(userId, goodsId);
        if (cartCache == null) {
            String message = "增加商品数据失败，购物车中无此商品！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        CartPO.CartInfo cartInfo = cartCache.getCartInfo();
        Integer originalNum = cartInfo.getGoodsNum();
        Integer newNum = originalNum + num;

        // 你可能需要在此检查新的数量是否超出允许的范围

        cartCacheRepository.updateGoodsNumByUserAndGoods(userId, goodsId, newNum);
        return newNum;
    }

    /**
     * 减少购物车中的商品的数量
     *
     * @param userId  用户ID
     * @param goodsId 商品ID
     * @param num     减少的商品的数量
     * @return 新的数量
     */
    private Integer reduceNum(Long userId, Long goodsId, Integer num) {
        checkGoodsState(goodsId);

        CartPO cartCache = cartCacheRepository.getByUserAndGoods(userId, goodsId);
        if (cartCache == null) {
            String message = "减少商品数据失败，购物车中无此商品！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        CartPO.CartInfo cartInfo = cartCache.getCartInfo();
        Integer originalNum = cartInfo.getGoodsNum();

        Integer newNum = originalNum - num;
        if (newNum <= 0) {
            cartCacheRepository.deleteByUserAndGoods(userId, goodsId);
            return 0;
        }

        cartCacheRepository.updateGoodsNumByUserAndGoods(userId, goodsId, newNum);
        return newNum;
    }

    /**
     * 检查商品状态，包括：是否存在，是否上架
     *
     * @param goodsId 商品ID
     */
    private void checkGoodsState(Long goodsId) {
        GoodsStandardVO goods = goodsRepository.getStandardById(goodsId);
        if (goods == null) {
            String message = "操作失败，商品数量不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        if (!goods.getIsPutOn().equals(PUT_ON_STATE_ON)) {
            String message = "操作失败，此商品已下架！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }
    }

}
